package main

import "fmt"

func main() {
	var a Animal
	a = Dog{}
	fmt.Println(a.Speak()) // 输出: Woof!
	a = Cat{}
	fmt.Println(a.Speak()) // 输出: Meow!

}

// 定义接口
type Animal interface {
	Speak() string
}

// 定义结构体
type Dog struct{}
type Cat struct{}

// 类型实现接口方法即可（隐式）

func (d Dog) Speak() string {
	return "Woof!"
}

func (c Cat) Speak() string {
	return "Meow!"
}

// Go 的泛型在运行时保留了类型信息，
// 不像Java退化成 interface{} 或 Object，
// 也不是完全的单态化（不像 Rust），而是一个折中方案

// Go 的泛型不会在运行时丢失类型信息，你仍然可以用 reflect.TypeOf 看到具体类型
// Go 不会为每个类型都生成一份代码，而是根据**类型的“形状”（shape）**来分组共享代码
// 编译器把泛型类型按**内存布局（shape）**分组，比如：
// 所有指针类型（*T、string、slice、map、chan、interface）共享一份代码。
// 所有 8 字节以内的值类型（如 int64、float64）共享一份代码。
// 每组共享一份代码，但通过一个**字典（dictionary）**在运行时传递类型信息（比如类型大小、对齐、方法表等

// Go 的 interface 是“见鸭子就是鸭子”；Rust 的 trait 是“先签合同再认鸭子，合同还得带在身上”